package com.github.baichuan.application.scaffold.rest.controller;

import com.github.baichuan.application.scaffold.rest.domain.application.Application;
import com.github.baichuan.application.scaffold.rest.domain.application.ApplicationService;
import com.github.baichuan.application.scaffold.rest.domain.application.Realm;
import com.github.baichuan.application.scaffold.rest.domain.application.RealmService;
import com.github.baichuan.application.scaffold.rest.dto.application.ApplicationForm;
import com.github.baichuan.application.scaffold.rest.dto.application.ApplicationTableView;
import com.github.baichuan.application.scaffold.rest.dto.application.ApplicationQueryCriteria;
import com.github.baichuan.application.scaffold.rest.jpa.application.ApplicationSpecification;
import com.github.baichuan.mapping.BeanMapper;
import com.github.baichuan.web.dto.Pagination;
import com.github.baichuan.web.dto.PaginationCriteria;
import com.github.baichuan.web.dto.Result;
import com.github.baichuan.web.ui.select.OptionGroup;
import com.github.baichuan.web.ui.select.OptionItem;
import com.github.baichuan.web.servlet.Restful;
import com.github.baichuan.web.ui.select.SelectUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedList;
import java.util.List;

@RestController
@Tag(name = "应用平台")
@RequestMapping("/application")
public class ApplicationController {
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private RealmService realmService;

    @Operation(summary = "查询")
    @PostMapping("/query")
    public ResponseEntity<Pagination<ApplicationTableView>> query(@RequestBody @Valid PaginationCriteria<ApplicationQueryCriteria> paginationCriteria){
        ApplicationSpecification specification = paginationCriteria.getCriteria().specification();
        Page<Application> page = applicationService.query(specification, paginationCriteria.pageable(ApplicationTableView.class));
        return ResponseEntity.ok(Pagination.of(page).map(ApplicationTableView.class));
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取表单信息")
    public ResponseEntity<ApplicationForm> get(@PathVariable("id") String id){
        Application application = applicationService.find(id);
        ApplicationForm form = BeanMapper.map(application, ApplicationForm.class);
        return ResponseEntity.ok(form);
    }

//    @GetMapping("/{code}")
//    @Operation(summary = "获取应用信息")
//    public ResponseEntity get(@PathVariable("code") String code){
//        Application application = applicationService.findByCode(code);
//        Map<String, Object> result = new HashMap<>();
//        result.put("name", application.getName().trim());
//        result.put("code", application.getCode());
//        return ResponseEntity.ok(result);
//    }

    @PostMapping
    @Operation(summary = "添加")
    public ResponseEntity<Result> add(@RequestBody @Valid ApplicationForm form) {
        Result result = applicationService.add(form);
        return Restful.created(result);
    }

    @PutMapping("/{id}")
    @Operation(summary = "修改")
    public ResponseEntity<Result> edit(@PathVariable("id") String id, @RequestBody @Valid ApplicationForm form) {
        Result result = applicationService.edit(id, form);
        return Restful.response(result);
    }

    @GetMapping("/tenant/options")
    @Operation(summary = "租户模式选项")
    public ResponseEntity<OptionItem[]> tenant() throws IllegalAccessException {
        OptionItem[] options = SelectUtils.options(Application.TenantMode.class);
        return ResponseEntity.ok(options);
    }

    @GetMapping("/option-group")
    @Operation(summary = "应用选项")
    public ResponseEntity<List<OptionGroup>> optionGroup() {
        List<OptionGroup> groups = new LinkedList<>();
        for (Realm realm : realmService.findAll()) {
            List<Application> applications = applicationService.findByRealm(realm);
            if(applications.size() > 0) {
                OptionItem[] items = applications.stream().map(x -> OptionItem.of(x.getName(), x.getCode())).toArray(OptionItem[]::new);
                groups.add(OptionGroup.of(realm.getName(), items));
            }
        }
        return ResponseEntity.ok(groups);
    }
}